package com.chenyun.boot.datasource.plugin;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.chenyun.common.annotation.DataDict;
import com.chenyun.common.constants.SysConstants;
import com.chenyun.common.context.SpringContext;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 格式化字典回显插件
 *
 * @author: Lonni
 * @date: 2022/10/8 0008 15:58
 */
//@Intercepts({
//        @Signature(type = ResultSetHandler.class,
//                method = "handleResultSets",
//                args = Statement.class)
//})
    @Deprecated
public class DictFormatterPlugin implements Interceptor {
    static Logger log = LoggerFactory.getLogger(DictFormatterPlugin.class);
    //存储实体中需要翻译的字典集合
    private final static List<CacheEntity> CACHE_ENTITIES = new ArrayList<>();



    /**
     * 拦截方法
     *
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        log.info("进入mybatis字典翻译插件...");
        Object result = invocation.proceed();

        Class currentClass = null;
        String entityName = "";

        List<Object> resultList=new ArrayList<>();
        if (result instanceof List) {
            List listResult = (List) result;
            if (CollectionUtil.isEmpty(listResult)) {
                return result;
            }
            currentClass = listResult.get(0).getClass();
            resultList.addAll(listResult);
        } else {
            currentClass = result.getClass();
            resultList.add(result);
        }
        entityName = currentClass.getName();
        //是否存在注解
        boolean translationInformation = getTranslationInformation(currentClass, result);
        if (!translationInformation){
            return  result;
        }
        RedisTemplate redisTemplate = SpringContext.getBean(RedisTemplate.class);
        for (Object o : resultList) {
            String finalEntityName = entityName;
            CacheEntity cacheEntity = CACHE_ENTITIES.stream().filter(p -> p.entityName.equals(finalEntityName)).findFirst().get();
            List<CacheEntityField> fields = cacheEntity.getFields();
            for (CacheEntityField field : fields) {
                String fieldName = field.getFieldName();
                //拿到字典名称
                String dictType = field.getDictType();
                //拿到当前字段值
                Object fieldValue = ReflectUtil.getFieldValue(o, fieldName);
                // redis中查询
                String keyString = SysConstants.SYS_DICT_KEY + dictType;
                Object cacheObj = redisTemplate.opsForValue().get(keyString);
                JSONArray jsonArray = JSONUtil.parseArray(cacheObj);
//                jsonArray.stream().filter(p->p.)
//                if (Objects.nonNull(cacheObj)) {
//                    List<SysDictData> dictDatas = (List<SysDictData>) cacheObj;
//                    return dictDatas;
//                }



            }


        }











        return null;
    }

    /**
     * 代理
     *
     * @param target
     * @return
     */
    @Override
    public Object plugin(Object target) {
        return Interceptor.super.plugin(target);
    }

    /**
     * 设置插件的属性  <bean > <propertie>s</propertie></bean>
     *
     * @param properties
     */
    @Override
    public void setProperties(Properties properties) {
        Interceptor.super.setProperties(properties);
    }


    /**
     * 判断是否需要翻译字典
     *
     * @param aclass
     * @param result
     * @return
     */
    boolean getTranslationInformation(Class aclass, Object result) {
        String name = aclass.getName();
        Optional<CacheEntity> firstCacheEntity = CACHE_ENTITIES.stream().filter(p -> p.entityName.equals(name)).findFirst();
        if (firstCacheEntity.isPresent()) {
            return true;
        }
        CacheEntity cacheEntity = new CacheEntity();
        List<CacheEntityField> fieldList = new ArrayList<>();
        Boolean hasAnnation = false;
        //不存在 解析
        Field[] declaredFields = aclass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            DataDict dataDictAnnotation = declaredField.getAnnotation(DataDict.class);
            if (dataDictAnnotation == null) {
                continue;
            }
            //加入
            fieldList.add(new CacheEntityField(declaredField.getName(), dataDictAnnotation.type()));
            hasAnnation = true;
        }
        cacheEntity.setEntityName(name);
        cacheEntity.setFields(fieldList);
        CACHE_ENTITIES.add(cacheEntity);
        return hasAnnation;
    }


    private static final class CacheEntity {
        private String entityName;
        private List<CacheEntityField> fields;

        public String getEntityName() {
            return entityName;
        }

        public void setEntityName(String entityName) {
            this.entityName = entityName;
        }

        public List<CacheEntityField> getFields() {
            return fields;
        }

        public void setFields(List<CacheEntityField> fields) {
            this.fields = fields;
        }
    }

    private static final class CacheEntityField {
        //字段名称
        private String fieldName;
        // 字典type 一级 如:dict_sex
        private String dictType;
//        //对应的字典code   如: dict_sex 1
//        private String dictCode;

        public CacheEntityField() {
        }

        public CacheEntityField(String fieldName, String dictType) {
            this.fieldName = fieldName;
            this.dictType = dictType;
        }

        public String getFieldName() {
            return fieldName;
        }

        public void setFieldName(String fieldName) {
            this.fieldName = fieldName;
        }

        public String getDictType() {
            return dictType;
        }

        public void setDictType(String dictType) {
            this.dictType = dictType;
        }

//        public String getDictCode() {
//            return dictCode;
//        }
//
//        public void setDictCode(String dictCode) {
//            this.dictCode = dictCode;
//        }
    }


}
